/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bs.facturacion.modelo;

import bs.global.auditoria.AuditoriaListener;
import bs.global.modelo.Auditoria;
import bs.global.modelo.Moneda;
import bs.stock.modelo.Deposito;
import bs.stock.modelo.Producto;
import bs.stock.modelo.UnidadMedida;
import bs.ventas.modelo.ConceptoVenta;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

/**
 *
 * @author ctrosch
 */
@Entity
@Table(name = "fc_movimiento_item")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TIPITM", discriminatorType = DiscriminatorType.STRING, length = 1)
@EntityListeners(AuditoriaListener.class)
public abstract class ItemMovimientoFacturacion implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)   
    @Column(name = "ID", nullable = false)
    private Integer id;
    
    @Column(name = "NROITM", nullable = false)
    private int nroitm;    
    
    @Column(name = "ID_IAPL", nullable = true)
    private Integer idItemAplicacion;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_MCAB", referencedColumnName = "ID", nullable = false)        
    private MovimientoFacturacion movimiento;
       
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_MAPL", referencedColumnName = "ID", nullable = false)        
    private MovimientoFacturacion movimientoAplicacion;
            
    @Column(name = "ID_MSTO", nullable = true)
    private Integer idMovimientoStock;

    /**
     * Movimiento original
     */
    @Column(name = "ID_MORIG", nullable = true)
    private Integer movimientoOriginal;
    
     /**
     * Movimiento inicial
     */
    @Column(name = "ID_MINIC", nullable = false)
    private Integer movimientoInicial;
    
    @JoinColumns({
        @JoinColumn(name = "MODCPT", referencedColumnName = "MODULO", nullable = false),
        @JoinColumn(name = "TIPCPT", referencedColumnName = "TIPCPT", nullable = false),
        @JoinColumn(name = "CODCPT", referencedColumnName = "CODIGO", nullable = false)
    })
    @ManyToOne(fetch = FetchType.LAZY)
    private ConceptoVenta concepto;
    
    @JoinColumn(name = "ARTCOD", referencedColumnName = "CODIGO", nullable = false)    
    @ManyToOne(fetch = FetchType.LAZY)
    private Producto producto;
    
    
    @JoinColumn(name = "ARTORI", referencedColumnName = "CODIGO", nullable = false)    
    @ManyToOne(fetch = FetchType.LAZY)
    private Producto productoOriginal;    

    //Numero de Serie
    @Column(name = "NSERIE", length = 30)
    private String nserie;
    //Numero de despacho
    @Column(name = "NDESPA", length = 30)
    private String ndespa;
    //Numero de envase
    @Column(name = "ENVASE", length = 30)
    private String envase;
    //Numero otros
    @Column(name = "NOTROS", length = 30)
    private String notros;
    //Numero de atributo
    @Column(name = "NATRIB", length = 30)
    private String natrib;
    //Numero de estante
    @Column(name = "NESTAN", length = 30)
    private String nestan;
    //Numero de ubicacion
    @Column(name = "NUBICA", length = 30)
    private String nubica;
    
    //Deposito
    @JoinColumn(name = "DEPOSI", referencedColumnName = "CODIGO", nullable = true)
    @ManyToOne(fetch = FetchType.LAZY)
    private Deposito deposito;

    //Sucursal o punto de venta
    @Column(name = "SUCURS", length = 6)
    private String sucursal;

    //Nro cta cliente    
    @Column(name = "NROCTA", length = 13)
    private String cliente;

    @Column(name = "NROSUB", length = 13)
    private String nrosub;

    @Column(name = "PRECIO", precision = 15, scale = 4)
    private BigDecimal precio;   
    @Column(name = "PRESEC", precision = 15, scale = 4)
    private BigDecimal precioSecundario;
    
    @JoinColumn(name = "COFLIS", referencedColumnName = "CODIGO")
    @ManyToOne(fetch = FetchType.LAZY)
    private Moneda monedaListaPrecio;
    
    @Column(name = "COTIZA", precision = 15, scale = 4)
    private BigDecimal cotizacion;
    
    @Column(name = "CANTID", precision = 15, scale = 4)    
    private BigDecimal cantidad;
    @Column(name = "CNTPEN", precision = 15, scale = 4)
    private BigDecimal cantidadPendiente;
    @Column(name = "CNTORI", precision = 15, scale = 4)
    private BigDecimal cantidadOriginal;
    
    //Total de linea
    @Column(name = "TOTLIN", precision = 15, scale = 4)
    private BigDecimal totalLinea;
    
    @Column(name = "TOTSEC", precision = 15, scale = 4)
    private BigDecimal totalLineaSecundario;
    
    @JoinColumn(name = "UNIMED", referencedColumnName = "CODIGO", nullable = false)
    @ManyToOne(fetch = FetchType.LAZY)
    private UnidadMedida unidadMedida;
    
    @Column(name = "FCHENT")
    @Temporal(TemporalType.DATE)
    private Date fechaEntregaDesde;
    @Column(name = "FCHHAS")
    @Temporal(TemporalType.DATE)
    private Date fechaEntregaHasta;

    @Column(name = "PCTBF1", precision = 15, scale = 4)
    private BigDecimal porcentajeBonificacion1;
    @Column(name = "PCTBF2", precision = 15, scale = 4)
    private BigDecimal porcentajeBonificacion2;
    @Column(name = "PCTBF3", precision = 15, scale = 4)
    private BigDecimal porcentajeBonificacion3;
    @Column(name = "PCTBF4", precision = 15, scale = 4)
    private BigDecimal porcentajeBonificacion4;
    @Column(name = "PCTBF5", precision = 15, scale = 4)
    private BigDecimal porcentajeBonificacion5;
    @Column(name = "PCTBF6", precision = 15, scale = 4)
    private BigDecimal porcentajeBonificacion6;    
    @Column(name = "PCTBFN", precision = 15, scale = 4)
    private BigDecimal porcentaTotalBonificacion;
    
    @Column(name = "CNTBON", precision = 15, scale = 4)
    private BigDecimal cantidadBonificada;
    
    @Lob
    @Column(name = "OBSERVA", length = 2147483647)
    private String observaciones;
       
    
    @Embedded
    private Auditoria auditoria;

    @Transient
    private BigDecimal pendiente;

    @Transient
    private BigDecimal precioListaConIVA;

    @Transient
    private BigDecimal precioFinalConIVA;

    @Transient
    private BigDecimal precioFinalSinIVA;

    @Transient
    private BigDecimal totalPendienteSinIVA;

    @Transient
    private BigDecimal totalPendienteConIVA;

    @Transient
    private BigDecimal totalLineaSinIVA;

    @Transient    
    private BigDecimal totalLineaConIVA;
    
    @Transient    
    private boolean todoOk;
    

    public ItemMovimientoFacturacion() {
           
        precio = BigDecimal.ZERO;
        precioSecundario = BigDecimal.ZERO;
        cantidad = BigDecimal.ZERO;                
        cantidadBonificada = BigDecimal.ZERO; 
        
        totalLinea = BigDecimal.ZERO;
        totalLineaSecundario = BigDecimal.ZERO;
        
        
        porcentajeBonificacion1 = BigDecimal.ZERO;
        porcentajeBonificacion2 = BigDecimal.ZERO;
        porcentajeBonificacion3 = BigDecimal.ZERO;
        porcentajeBonificacion4 = BigDecimal.ZERO;
        porcentajeBonificacion5 = BigDecimal.ZERO;
        porcentajeBonificacion6 = BigDecimal.ZERO;
        porcentaTotalBonificacion = BigDecimal.ZERO;
        
        cotizacion = BigDecimal.ONE;        
        auditoria = new Auditoria();

        
    }

    public ItemMovimientoFacturacion(Producto producto) {

        precio = BigDecimal.ZERO;
        precioSecundario = BigDecimal.ZERO;
        cantidad = BigDecimal.ZERO;                
        cantidadBonificada = BigDecimal.ZERO;   
        
        totalLinea = BigDecimal.ZERO;
        totalLineaSecundario = BigDecimal.ZERO;
        
        porcentajeBonificacion1 = BigDecimal.ZERO;
        porcentajeBonificacion2 = BigDecimal.ZERO;
        porcentajeBonificacion3 = BigDecimal.ZERO;
        porcentajeBonificacion4 = BigDecimal.ZERO;
        porcentajeBonificacion5 = BigDecimal.ZERO;
        porcentajeBonificacion6 = BigDecimal.ZERO;
        porcentaTotalBonificacion = BigDecimal.ZERO;
        
        cotizacion = BigDecimal.ONE;        
        auditoria = new Auditoria();
        this.producto = producto;
        
        if(producto!=null){
            productoOriginal = producto;
            concepto = producto.getConceptoVenta();
            //cuenta = producto.getCuentaVenta();            
        }
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    
    public String getEnvase() {
        return envase;
    }

    public Integer getIdItemAplicacion() {
        return idItemAplicacion;
    }

    public void setIdItemAplicacion(Integer idItemAplicacion) {
        this.idItemAplicacion = idItemAplicacion;
    }

    public void setEnvase(String envase) {
        this.envase = envase;
    }

    public BigDecimal getCantidadPendiente() {
        return cantidadPendiente;
    }

    public void setCantidadPendiente(BigDecimal cantidadPendiente) {
        this.cantidadPendiente = cantidadPendiente;
    }

    public Date getFechaEntregaDesde() {
        return fechaEntregaDesde;
    }

    public void setFechaEntregaDesde(Date fechaEntregaDesde) {
        this.fechaEntregaDesde = fechaEntregaDesde;
    }

    public Date getFechaEntregaHasta() {
        return fechaEntregaHasta;
    }

    public Integer getIdMovimientoStock() {
        return idMovimientoStock;
    }

    public void setIdMovimientoStock(Integer idMovimientoStock) {
        this.idMovimientoStock = idMovimientoStock;
    }

    public Integer getMovimientoOriginal() {
        return movimientoOriginal;
    }

    public void setMovimientoOriginal(Integer movimientoOriginal) {
        this.movimientoOriginal = movimientoOriginal;
    }

    public Integer getMovimientoInicial() {
        return movimientoInicial;
    }

    public void setMovimientoInicial(Integer movimientoInicial) {
        this.movimientoInicial = movimientoInicial;
    }

    public BigDecimal getPrecioSecundario() {
        return precioSecundario;
    }

    public void setPrecioSecundario(BigDecimal precioSecundario) {
        this.precioSecundario = precioSecundario;
    }

    public BigDecimal getCotizacion() {
        return cotizacion;
    }

    public void setCotizacion(BigDecimal cotizacion) {
        this.cotizacion = cotizacion;
    }
    
    public BigDecimal getCantidad() {
        return cantidad;
    }

    public void setCantidad(BigDecimal cantidad) {
        this.cantidad = cantidad;
    }

   
    public UnidadMedida getUnidadMedida() {
        return unidadMedida;
    }

    public void setUnidadMedida(UnidadMedida unidadMedida) {
        this.unidadMedida = unidadMedida;
    }

    public BigDecimal getPorcentajeBonificacion1() {
        return porcentajeBonificacion1;
    }

    public void setPorcentajeBonificacion1(BigDecimal porcentajeBonificacion1) {
        this.porcentajeBonificacion1 = porcentajeBonificacion1;
    }

    public BigDecimal getPorcentajeBonificacion2() {
        return porcentajeBonificacion2;
    }

    public void setPorcentajeBonificacion2(BigDecimal porcentajeBonificacion2) {
        this.porcentajeBonificacion2 = porcentajeBonificacion2;
    }

    public BigDecimal getPorcentajeBonificacion3() {
        return porcentajeBonificacion3;
    }

    public void setPorcentajeBonificacion3(BigDecimal porcentajeBonificacion3) {
        this.porcentajeBonificacion3 = porcentajeBonificacion3;
    }

    public BigDecimal getPorcentajeBonificacion4() {
        return porcentajeBonificacion4;
    }

    public void setPorcentajeBonificacion4(BigDecimal porcentajeBonificacion4) {
        this.porcentajeBonificacion4 = porcentajeBonificacion4;
    }

    public BigDecimal getPorcentajeBonificacion5() {
        return porcentajeBonificacion5;
    }

    public void setPorcentajeBonificacion5(BigDecimal porcentajeBonificacion5) {
        this.porcentajeBonificacion5 = porcentajeBonificacion5;
    }

    public BigDecimal getPorcentajeBonificacion6() {
        return porcentajeBonificacion6;
    }

    public void setPorcentajeBonificacion6(BigDecimal porcentajeBonificacion6) {
        this.porcentajeBonificacion6 = porcentajeBonificacion6;
    }

    public BigDecimal getPorcentaTotalBonificacion() {
        return porcentaTotalBonificacion;
    }

    public void setPorcentaTotalBonificacion(BigDecimal porcentaTotalBonificacion) {
        this.porcentaTotalBonificacion = porcentaTotalBonificacion;
    }

    public BigDecimal getCantidadBonificada() {
        return cantidadBonificada;
    }

    public void setCantidadBonificada(BigDecimal cantidadBonificada) {
        this.cantidadBonificada = cantidadBonificada;
    }

    public String getObservaciones() {
        return observaciones;
    }

    public void setObservaciones(String observaciones) {
        this.observaciones = observaciones;
    }
    
    public void setFechaEntregaHasta(Date fechaEntregaHasta) {
        this.fechaEntregaHasta = fechaEntregaHasta;
    }

    public MovimientoFacturacion getMovimiento() {
        return movimiento;
    }

    public void setMovimiento(MovimientoFacturacion movimiento) {
        this.movimiento = movimiento;
    }

    public String getNatrib() {
        return natrib;
    }

    public void setNatrib(String natrib) {
        this.natrib = natrib;
    }

    public String getNdespa() {
        return ndespa;
    }

    public void setNdespa(String ndespa) {
        this.ndespa = ndespa;
    }

    public String getNestan() {
        return nestan;
    }

    public void setNestan(String nestan) {
        this.nestan = nestan;
    }

    public String getNotros() {
        return notros;
    }

    public void setNotros(String notros) {
        this.notros = notros;
    }

    public String getSucursal() {
        return sucursal;
    }

    public void setSucursal(String sucursal) {
        this.sucursal = sucursal;
    }

    public String getCliente() {
        return cliente;
    }

    public void setCliente(String cliente) {
        this.cliente = cliente;
    }
    
    public String getNrosub() {
        return nrosub;
    }

    public void setNrosub(String nrosub) {
        this.nrosub = nrosub;
    }

    public String getNserie() {
        return nserie;
    }

    public void setNserie(String nserie) {
        this.nserie = nserie;
    }

    public String getNubica() {
        return nubica;
    }

    public void setNubica(String nubica) {
        this.nubica = nubica;
    }

    public BigDecimal getPrecio() {
        return precio;
    }

    public void setPrecio(BigDecimal precio) {
        this.precio = precio;
    }

    public Producto getProducto() {
        return producto;
    }

    public void setProducto(Producto producto) {
        this.producto = producto;
    }
    
    public Deposito getDeposito() {
        return deposito;
    }

    public void setDeposito(Deposito deposito) {
        this.deposito = deposito;
    }

    public Moneda getMonedaListaPrecio() {
        return monedaListaPrecio;
    }

    public void setMonedaListaPrecio(Moneda monedaListaPrecio) {
        this.monedaListaPrecio = monedaListaPrecio;
    }
   
    public MovimientoFacturacion getMovimientoAplicacion() {
        return movimientoAplicacion;
    }

    public void setMovimientoAplicacion(MovimientoFacturacion movimientoAplicacion) {
        this.movimientoAplicacion = movimientoAplicacion;
    }

    public int getNroitm() {
        return nroitm;
    }

    public void setNroitm(int nroitm) {
        this.nroitm = nroitm;
    }

    public BigDecimal getPendiente() {
        return pendiente;
    }

    public void setPendiente(BigDecimal pendiente) {
        this.pendiente = pendiente;
    }

    public ConceptoVenta getConcepto() {
        return concepto;
    }

    public void setConcepto(ConceptoVenta concepto) {
        this.concepto = concepto;
    }

    public BigDecimal getCantidadOriginal() {
        return cantidadOriginal;
    }

    public void setCantidadOriginal(BigDecimal cantidadOriginal) {
        this.cantidadOriginal = cantidadOriginal;
    }
    
    public BigDecimal getTotalPendienteConIVA() {

        try {
            totalPendienteConIVA = BigDecimal.ZERO;                        
            if (pendiente != null) {

                BigDecimal bonif = precio.multiply(porcentaTotalBonificacion.divide(new BigDecimal(100)));
                BigDecimal impUnit = precio.add(bonif);
                BigDecimal impTotal = pendiente.multiply(impUnit);
                
//                if (codcpt.equals("V001")) {
//                    totalPendienteConIVA = impTotal.multiply(new BigDecimal(1.21));
//                }
//                if (codcpt.equals("V002")) {
//                    totalPendienteConIVA = impTotal.multiply(new BigDecimal(1.105));
//                }
//                if (codcpt.equals("V003")) {
//                    totalPendienteConIVA = impTotal;
//                }
            }

            return totalPendienteConIVA;
        } catch (Exception e) {
             
             return BigDecimal.ZERO;
        }
    }

    public void setTotalPendienteConIVA(BigDecimal totalPendienteConIVA) {
        this.totalPendienteConIVA = totalPendienteConIVA;
    }

    public BigDecimal getTotalPendienteSinIVA() {

        try {
            totalPendienteSinIVA = BigDecimal.ZERO;

            if (pendiente != null) {
                totalPendienteSinIVA = pendiente.multiply(precio.add(precio.multiply(porcentaTotalBonificacion.divide(new BigDecimal(100)))));
            }
            return totalPendienteSinIVA;
        } catch (Exception e) {            
            return BigDecimal.ZERO;
        }
    }

    public void setTotalPendienteSinIVA(BigDecimal totalPendienteSinIVA) {
        this.totalPendienteSinIVA = totalPendienteSinIVA;
    }

    public BigDecimal getTotalLineaConIVA() {

        try {
            if (cantidad != null) {

                totalLineaConIVA = BigDecimal.ZERO;
                BigDecimal bonif = precio.multiply(porcentaTotalBonificacion.divide(new BigDecimal(100)));
                BigDecimal impUnit = precio.add(bonif);
                BigDecimal impTotal = cantidad.multiply(impUnit);

            
                if (concepto.getCodigo().equals("V001")) {
                    totalLineaConIVA = impTotal.multiply(new BigDecimal(1.21));
                }
                if (concepto.getCodigo().equals("V002")) {
                    totalLineaConIVA = impTotal.multiply(new BigDecimal(1.105));
                }
                if (concepto.getCodigo().equals("V003")) {
                    totalLineaConIVA = impTotal;
                }
            }

            return totalLineaConIVA;

        } catch (Exception e) {

            return BigDecimal.ZERO;
        }
    }

    public void setTotalLineaConIVA(BigDecimal totalLineaConIVA) {
        this.totalLineaConIVA = totalLineaConIVA;
    }

    public BigDecimal getTotalLineaSinIVA() {

        try {
            totalLineaSinIVA = BigDecimal.ZERO;

            if (cantidad != null) {
                totalLineaSinIVA = cantidad.multiply(precio.add(precio.multiply(porcentaTotalBonificacion.divide(new BigDecimal(100)))));
            }
            return totalLineaSinIVA;
        } catch (Exception e) {
            return BigDecimal.ZERO;
        }

    }

    public void setTotalLineaSinIVA(BigDecimal totalLineaSinIVA) {
        this.totalLineaSinIVA = totalLineaSinIVA;
    }

    public BigDecimal getPrecioListaConIVA() {
        try {
            if (precio != null) {

                precioListaConIVA = BigDecimal.ZERO;

                if (concepto.getCodigo().equals("V001")) {
                    precioListaConIVA = precio.multiply(new BigDecimal(1.21));
                }
                if (concepto.getCodigo().equals("V002")) {
                    precioListaConIVA = precio.multiply(new BigDecimal(1.105));
                }
                if (concepto.getCodigo().equals("V003")) {
                    precioListaConIVA = precio;
                }
            }

            return precioListaConIVA;

        } catch (Exception e) {

            return BigDecimal.ZERO;
        }

    }

    public void setPrecioListaConIVA(BigDecimal precioListaConIVA) {
        this.precioListaConIVA = precioListaConIVA;
    }

    public BigDecimal getPrecioFinalConIVA() {
        try {
            if (precio != null) {

                precioFinalConIVA = BigDecimal.ZERO;
                BigDecimal bonif = precio.multiply(porcentaTotalBonificacion.divide(new BigDecimal(100)));
                BigDecimal impUnit = precio.add(bonif);

                if (concepto.getCodigo().equals("V001")) {
                    precioFinalConIVA = impUnit.multiply(new BigDecimal(1.21));
                }
                if (concepto.getCodigo().equals("V002")) {
                    precioFinalConIVA = impUnit.multiply(new BigDecimal(1.105));
                }
                if (concepto.getCodigo().equals("V003")) {
                    precioFinalConIVA = impUnit;
                }
            }

            return precioFinalConIVA;

        } catch (Exception e) {

            return BigDecimal.ZERO;
        }
    }

    public void setPrecioFinalConIVA(BigDecimal precioFinalConIVA) {
        this.precioFinalConIVA = precioFinalConIVA;
    }
    
    public BigDecimal getPrecioFinalSinIVA() {

        try {
            if (precio != null) {
                
                precioFinalSinIVA = BigDecimal.ZERO;
                BigDecimal bonif = precio.multiply(porcentaTotalBonificacion.divide(new BigDecimal(100)));
                BigDecimal impUnit = precio.add(bonif);
                precioFinalSinIVA = impUnit;
            }

            return precioFinalSinIVA;

        } catch (Exception e) {

            return BigDecimal.ZERO;
        }
    }

    public void setPrecioFinalSinIVA(BigDecimal precioFinalSinIVA) {
        this.precioFinalSinIVA = precioFinalSinIVA;
    }

    public Producto getProductoOriginal() {
        return productoOriginal;
    }

    public void setProductoOriginal(Producto productoOriginal) {
        this.productoOriginal = productoOriginal;
    }
    
    public Auditoria getAuditoria() {
        return auditoria;
    }

    public void setAuditoria(Auditoria auditoria) {
        this.auditoria = auditoria;
    }

    public BigDecimal getTotalLinea() {
        return totalLinea;
    }

    public void setTotalLinea(BigDecimal totalLinea) {
        this.totalLinea = totalLinea;
    }

    public boolean isTodoOk() {
        return todoOk;
    }

    public void setTodoOk(boolean todoOk) {
        this.todoOk = todoOk;
    }

    public BigDecimal getTotalLineaSecundario() {
        return totalLineaSecundario;
    }

    public void setTotalLineaSecundario(BigDecimal totalLineaSecundario) {
        this.totalLineaSecundario = totalLineaSecundario;
    }
    
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 41 * hash + (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ItemMovimientoFacturacion other = (ItemMovimientoFacturacion) obj;
        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    
    @Override
    public String toString() {
        return "ItemMovimientoFacturacion{" + "id=" + this.id  + '}';
    }

    

}
